{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random,math,copy,time\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.ensemble import (RandomForestClassifier,GradientBoostingClassifier)\n",
    "from sklearn import tree\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.model_selection import train_test_split,cross_val_score\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn import preprocessing, svm\n",
    "from tqdm import tqdm\n",
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m=20  # Problem dimension (number of decision variables\n",
    "Ap=0.1  # Awareness probability\n",
    "fl=2   # Flight length (fl)\n",
    "wf=1.2# wf is used to control the importance of classification accuracy and number of selected features.\n",
    "d=67600# Flock (population) size\n",
    "lt=67600"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "imo=pd.read_csv('importance_feature_AD-MCI.csv')\n",
    "imo=imo.iloc[:,1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "features=[i for i in range(0,lt)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def init():   #initialization function\n",
    "    df2=pd.DataFrame(np.ones((m,d),dtype='int'),columns=features)\n",
    "    return df2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# this defines the fitness of each crow by calculating their accuracy and no features selected using the below formula\n",
    "def fitness(df2):      # fitness function whose 1 parameter takes the crows and their position as input\n",
    "    fnt=np.zeros((m,1))  # fnt is the fitness function\n",
    "    for k in tqdm(range(m)):    \n",
    "        global sel\n",
    "        sel=0\n",
    "        imp=0        \n",
    "        if (df2.iloc[k,:]==0.0).all()==True:\n",
    "            df2.iloc[k,:]=1.0        \n",
    "        #adding importance of each feature a crow into the variable temp\n",
    "        for p in features:\n",
    "            if df2.loc[k,p]==1.0:\n",
    "                sel += 1\n",
    "                #print(imo[p])\n",
    "                imp=imp+imo[p]              \n",
    "            #q=q+1\n",
    "        lf=sel\n",
    "        #divide=lf/lt\n",
    "        fnt[k]=imp+wf*(1-float(lf/lt))     # fitness formula      \n",
    "    return fnt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z=init()   #crow memory with initial position\n",
    "tmax=50 #   # Maximum number of iterations (itermax)\n",
    "xn=z.copy()  # the position of the crow\n",
    "mem=init()  # memory is initialized using the init function\n",
    "xnew=(xn).copy()   # the positions of the crow\n",
    "ft=fitness(xn)\n",
    "print(ft)\n",
    "plotit=[]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "tottime=0\n",
    "tmax=50\n",
    "#s=pd.DataFrame(z)\n",
    "#print(\"got s\")    # it is a formula to convert positions of each crow into 0 and 1 \n",
    "for t in range(tmax):\n",
    "    print(t)# no of iterations\n",
    "    time1=time.time()\n",
    "   \n",
    "    xnew_list = []\n",
    "    plotit.append(ft.max())\n",
    "    num = random.randint(0,m-1)  \n",
    "   # Generation of random candidate crows for following (chasing)\n",
    "    for i in tqdm(range(m)):   \n",
    "       \n",
    "        r=random.random()\n",
    "        if r>=Ap:\n",
    "            \n",
    "            xnew_list.append((xn.loc[i,:]+fl*r*(mem.loc[num,:]-xn.loc[i,:])).tolist())# Generation of a new position for crow i (state 1)\n",
    "            \n",
    "        else:\n",
    "            \n",
    "            xnew_list.append((xnew.loc[i,:].apply(lambda lam:random.random())).tolist())   # Generation of a new position for crow i (state 2)\n",
    "            \n",
    "            \n",
    "    xnew = pd.DataFrame(xnew_list)\n",
    "    del xnew_list\n",
    "    print('transpose')\n",
    "    xnew= 1/( 1 + np.expm1(( 10*(xnew-0.5))))    #  formula to convert positions of each crow into 0 and 1\n",
    "    print('exp')\n",
    "    xnew=xnew.apply(lambda l:l>=random.random()).astype(int)\n",
    "    print('apply lambda')\n",
    "    xn=xnew.copy()     \n",
    "    print('copied')\n",
    "    # it is the updated binary position of each crow\n",
    "    #feasibility test\n",
    "    # this is done so that to check if atleast one position of the crow has value equal to 1. if it is not true then every\n",
    "    # position value of the crow is made 1.\n",
    "    for i in tqdm(range(m)):\n",
    "        \n",
    "        if ((xn.loc[i,:])==0.0).all()==True:\n",
    "            xn.loc[i,:]=1.0\n",
    "    \n",
    "    print('running fitness')\n",
    "    ft_new=fitness(xn).reshape(ft.shape)# here the accuracy of each crows are calculated.\n",
    "\n",
    "    print('fitness done')\n",
    "    for i in tqdm(range(m)):\n",
    "         \n",
    "        if ft_new[i]>ft[i]:\n",
    "            ft[i]=ft_new[i]\n",
    "            for j in features:\n",
    "                mem.loc[i,j]= xn.loc[i,j]\n",
    "    \n",
    "    print('complete'+str(t))\n",
    "    time2=time.time()\n",
    "    tottime=tottime+(time2-time1)\n",
    "print(tottime/t+1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# here the accuracy of each crows are calculated.\n",
    "\n",
    "neigh = KNeighborsClassifier(n_neighbors=3)\n",
    "rforest = RandomForestClassifier()\n",
    "dtree = tree.DecisionTreeClassifier()\n",
    "clf = svm.SVC()\n",
    "\n",
    "nacc1=np.zeros((m,1),dtype='float64')\n",
    "rfacc1=np.zeros((m,1),dtype='float64')\n",
    "dtacc1=np.zeros((m,1),dtype='float64')\n",
    "clf1=np.zeros((m,1),dtype='float64')\n",
    "\n",
    "q=0\n",
    "for i in tqdm(range(m)):\n",
    "    print(i)\n",
    "    select=[]\n",
    "    for p in list(features):\n",
    "        if mem.loc[i,p]==1:\n",
    "            select.insert(q,p)\n",
    "            q=q+1\n",
    "    neigh.fit(x_train[select], y_train)\n",
    "    neigh.predict(x_test[select])\n",
    "    nacc1[i]=neigh.score(x_test[select],y_test) \n",
    "\n",
    "    \n",
    "    rforest.fit(x_train[select], y_train)\n",
    "    rforest.predict(x_test[select])\n",
    "    rfacc1[i]=rforest.score(x_test[select],y_test) \n",
    "\n",
    "    dtree.fit(x_train[select], y_train)\n",
    "    dtree.predict(x_test[select])\n",
    "    dtacc1[i]=dtree.score(x_test[select],y_test)\n",
    "\n",
    "select=[]\n",
    "for p in list(features):\n",
    "    if mem.loc[i,p]==1:\n",
    "        select.insert(q,p)\n",
    "        q=q+1\n",
    "\n",
    "print (nacc1.max(), rfacc1.max(), dtacc1.max()) # the crow with maximum accuracy is printed"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
